Technical Note TN2058
The Font Panel for Carbon API

目次

このテクニカルノートは、Mac OS X において、Carbon アプリケーションから、フォントパネルを表示しやり取りするために使用する API について説明します

ほとんどの Carbon アプリケーションでは、ユーザが、フォントメニュー(Standard Font Menu APIを使って作成、維持されているものが望ましい)を使ってフォントを選択できるようにしています。それに対し、Cocoa アプリケーションの場合、ユーザは、標準のフォントパネルフローティングダイアログを使ってフォントを選択します。このダイアログは、Objective C および Cocoa を使って、NSFontPanel クラスによって実装されており、Carbon アプリケーションからは直接アクセスできません。Carbon API 対応のフォントパネルは、Mac OS X 上で Carbon アプリケーションのためにフォントパネルへのアクセスを提供します。

このテクニカルノートは、Mac OS X の Carbon アプリケーションにおいて、ユーザがテキストのフォント、スタイル、サイズを指定する手段としてフォントパネルを使えるようにしたいと考えるアプリケーションの開発者に向けて書かれています。

[2002 年 9 月 5 日]






Carbon でのフォントパネルの使用

この節では、Carbon アプリケーションからのフォントパネルの使用に関する概略を説明し、その後、API の詳細について説明します。

ユーザは、アプリケーションの適切なメニュー(「フォント」メニューから フォントパネル…など)を選択したり、ボタンをクリックしたり、またはその他のしくみを使うなどして、フォントパネルを開きます。アプリケーションは、それに応じて、kHICommandShowHideFontPanel を使って Carbon Event Manager コマンドイベントは発行します。標準の Carbon アプリケーションのイベントハンドラーは、このイベントを検出し、ShowHideFontPanel を呼び出すことでそれに応えます。


注意:
アプリケーションは、Carbon Event Manager コマンドイベントを発行せずに、ユーザによるメニュー項目やその他のヒューマンインタフェースの選択に応じて、ShowHideFontPanel を直接呼び出すことによって、フォントパネルを開くこともできます。


Carbon イベントターゲット(通常はコントロールやウィンドウ)がフォーカスを得ると、アプリケーションは SetFontInfoForSelection を呼び出し、現在選択されているテキストのスタイルラン情報をフォントパネルに渡します。また、アプリケーションは、SetFontInfoForSelection によりフォントパネル関連の Carbon イベントの送り先であるイベントターゲットを指定できます。

フォーカスを得てターゲットの選択内容が変わるたびに、またはプログラム処理によってスタイルランが変更されると、アプリケーションは、SetFontInfoForSelection を呼び出します。この関数が呼び出されたときにフォントパネルが表示されていれば、フォントパネルに渡されたスタイルラン情報を反映し内容が更新されます。フォントパネルが表示されていない場合には、ユーザが視認できる変化はありませんが、SetFontInfoForSelection によって提供された情報は保存され、次にフォントパネルが表示されたときに正しい設定が表示されます。

フォントパネルを開く前に、アプリケーションが SetFontInfoForSelection を呼び出した場合は、選択したフォントの情報はフォントパネルに渡されており、フォントパネルが開いたときに表示されます。そうでない場合は、フォントパネルは、何も選択されていない状態で開きます。

ユーザがフォントパネルでフォントの設定を選択すると、アプリケーションは、フォントパネルからフォント選択 Carbon イベントを受け取ります。フォントパネルにおいてユーザが選択した設定は、kEventFontSelection イベントのイベントパラメータとして渡されます。アプリケーションは、単純にイベントから可能な限り多くのパラメータを抽出し、必要に応じてフォント設定を適用します。

ユーザが、フォントパネルを閉じると、ウィンドウが閉じられたことをアプリケーションに知らせる Carbon イベントが発行されます。


注意:
Carbon アプリケーションがまだ、旧式の WaitNextEvent イベントループを使っている場合も、フォントパネルをサポートするには Carbon イベントハンドラをインストールする必要があります。特に、次に詳しく説明する、フォントパネルが閉じられているときおよび選択時のイベントを処理する場合に必要です。


先頭に戻る

フォントパネルの API

SetFontInfoForSelection

アプリケーションは、SetFontInfoForSelection を呼び出し、現在選択されているテキストのスタイルランに関する情報をフォントパネルに提供します。これによりフォントパネルは情報を反映して、更新することができます。複数のスタイルランを指定できます。

    OSStatus SetFontInfoForSelection(
     OSType iStyleType,
     UInt32 iNumStyles,
     void* iStyles,
     HIObjectRef iFPEventTarget);

SetFontInfoForSelection は、さまざまな形式でスタイルラン情報を受け取ります。iStyleType がその形式を指定します。現在 2 つの値がサポートされています。

  • kFontSelectionATSUIType は、スタイルラン情報が ATSUStyle コレクションを使って指定されることを示します。
  • kFontSelectionQDType は、スタイルラン情報が FontSelectionQDStyle レコードを使って指定されることを示します。

iNumStyles は、 関数呼び出しの中で指定されている個別のスタイルランの数です。iNumStyles が 0 の場合は、フォントパネルの設定はクリアされます。

iStyles は、スタイルラン情報の配列へのポインタです。iStyleTypekFontSelectionATSUIType の場合、iStylesATSUStyle コレクションの配列を指します。iStyleTypekFontSelectionQDType の場合、iStylesFontSelectionQDStyle レコードの配列を指します。

iFPEventTarget は、以降のフォントパネルイベントの送信先である Carbon Event Manager ヒューマンインタフェースオブジェクトへの参照です。これは、現在フォーカスを得ているウィンドウまたはコントロールか、アプリケーション自身です。値は、ユーザがフォーカスを移すのに伴って、呼び出しごとに変えることができます。この値が NULL の場合、フォントパネルイベントは、GetApplicationEventTarget が返すアプリケーションターゲットにイベントを送ります。

返されるエラー状態は次のとおりです。

  • iNumStyles はゼロではないが iStyles が NULL の場合、または iNumStyles が指定されたスタイルランの数と異なる場合には paramErr が返されます。
  • 渡されたスタイルラン情報のいずれかの要素が、フォントパネルでの選択に必要とされる必要最小限の情報を含んでいない場合には fontSelectionStyleErr が返されます。

フォントパネルが表示されている時に、SetFontInfoForSelection がエラー状態を返した場合は、パネルの選択内容は変更されません。

SetFontInfoForSelection が戻ってきた後、iStyles が指すスタイルラン情報に割り当てられたメモリを解放するのはアプリケーションの役目です。

SetFontInfoForSelection を呼び出すと、フォントパネルが、スタイルラン情報の配列を走査し、フォントパネルを適宜更新します。iNumStyles が 0 の場合、iStylesNULL とみなされ、フォントパネル上のすべての選択はクリアされます。


注意:
現在フォントパネルは、iNumStyles が 1 より大きい場合は、どの項目も選択しません。しかし、将来この動作に変更があった場合に修正しなくて済むように、アプリケーションでは、すべてのスタイルランの情報を提供するようにしておいた方が良いでしょう。


フォントパネルが開かれてない時または表示されていない時でも、SetFontInfoForSelection は呼び出せます。フォントパネルが開かれる前、または フォントパネルが見えないときに呼び出した場合、フォントパネルは、後で表示された時に、SetFontInfoForSelection の最後の呼び出しで指定されたスタイル情報を表示します。

先頭に戻る

ATSUStyle

ATSUStyle オブジェクトを使用してスタイルラン情報を指定する場合、アプリケーションは、ATSUSetAttribute を呼び出すことによって、各 ATSUStyle にフォント属性を設定できます。アプリケーションは各 ATSUStyle に対し、少なくとも次のデータを提供する必要があります。

  • kATSUFontTagATSUFontID 型):選択されたテキストの ATSUFontID
  • kATSUFontSizeFixed 型):選択されたテキストのサイズ(ポイント数)

ATSUStyle オブジェクトの配列へのポインタを、SetFontInfoForSelection への呼び出しに含まれる iStyles パラメータの中で渡します。SetFontInfoForSelection が戻った後で、割り当てられた各 ATSUStyle オブジェクトに対して ATSUDisposeStyle を呼び出すのはアプリケーションの役目です。

 リスト 1 ATSUStyle を使った SetFontInfoForSelection の呼び出し

...
if (FPIsFontPanelVisible())
{
    OSStatus          status;
    ATSUStyle            aStyle;
    ATSUAttributeTag     atsuiTag[] = {kATSUFontTag, kATSUSizeTag};
    ByteCount            atsuiSize[] = {sizeof(ATSUFontID), sizeof(Fixed)};
    ATSUAttributeValuePtr   atsuiValue[2];

    status = ATSUCreateStyle(aStyle);

    /*
    属性値の配列に、正しい順序で、属性値へのポインタを代入する
    */
    atsuiValue[0] = &atsuiFontID;
    atsuiValue[1] = &atsuiSize;

    /*
    ATSUStyle の中で属性値を設定し、その情報をフォントパネルに送る
    */
    status = ATSUSetAttributes(aStyle, 2, atsuiTag, atsuiSize, atsuiValue);
    status = SetFontInfoForSelection(kFontSelectionATSUIType, 1, &aStyle, NULL);

    /*
    ATSUStyle を解放するのを忘れないように!
    */
    status = ATSUDisposeStyle(aStyle);
}
...

先頭に戻る

FontSelectionQDStyle

アプリケーションが、Quickdraw タイプのデータ型を使う場合は、FontSelectionQDStyle レコードを使ってスタイルラン情報を指定すると良いでしょう。

typedef struct
{
    UInt32 version;
    FMFontFamilyInstance instance;
    FMFontSize size;
    Boolean hasColor;
    RGBColor color;
}
FontSelectionQDStyle;

const UInt32 kCurrentFontSelectionQDStyleZero = 0;

version とは、レコードの現在のバージョン番号で、アプリケーションが、ヘッダファイルに定義されている適切な定数(現在は kCurrentFontSelectionQDStyleZero)に設定する必要があります。

instancesize は、Quickdraw フォントファミリ参照、スタイル指定、および書体のサイズを提供します。

hasColor が true の場合、 color は選択されたテキストの色を定義します。true でない場合、color は無視されます。


注意:
現在、Carbon アプリケーション対応のフォントパネルでは color をサポートしていません。


FontSelectionQDStyle レコードを使ってスタイル情報を指定する場合、リスト 2 に示すように、アプリケーションは、選択内容の各スタイルランごとにファミリ、スタイル、サイズを提供する必要があります。


注意:
現在フォントパネルは、輪郭や網掛けなどの Quickdraw 固有のスタイルはサポートしていません。


 リスト 2 FontSelectionQDStyle を使った SetFontInfoForSelection の呼び出し

/*
フォントパネルにフォントが変わったことを知らせる
*/
qdInfo.version = kFontSelectionQDStyleVersionZero;
qdInfo.instance = fontFamilyInstance;
qdInfo.size = fontSize;
GetFontInfoFromWindow(window, NULL, &(qdInfo.size));
qdInfo.hasColor = false;

status = SetFontInfoForSelection(kFontSelectionQDType,
        1, &qdInfo, NULL);
     

先頭に戻る

フォーカス変更の処理

ユーザがフォーカスを別に移したとき、フォーカスを手放すコンポーネントは、SetFontInfoForSelection を呼び出して、iNumStyles には 0 、iEventTarget には NULL を指定する必要があります。これにより、設定をクリアする必要があることをフォントパネルに伝えます。フォーカスを受け取ったコンポーネントは、その後 SetFontInfoForSelection を呼び出し、(iNumStyles が 0 の場合でも)新しいイベントターゲットとして自身を登録します。

ユーザのフォーカスは、キーボード入力の送り先であるアプリケーションのヒューマンインタフェース要素の一部であることを思い出してください。ウィンドウまたはコントロールの場合もあれば、その他のヒューマンインタフェース要素の場合もあります。この場合、ユーザフォーカスが変更されたことを知る必要があるのは、フォントパネルイベントの送り先のヒューマンインタフェース要素だけです(Carbon イベントおよびユーザフォーカスの詳細については、Carbon Event Manager に関する文献を参照してください)。

たとえば、アプリケーションが複数のウィンドウをサポートする場合には、kEventWindowFocusAcquired イベントおよび kEventWindowFocusRelinquish イベント(kEventClassWindow クラス)をキャッチし適宜 SetFontInfoForSelection を呼び出す Carbon イベントハンドラを、各ウィンドウにインストールできます。リスト 3 に、その場合のコード例を示します。

 リスト 3 ユーザフォーカスイベントハンドラからの SetFontInfoForSelection の呼び出し

...

/*
Carbon イベントハンドラの宣言
*/
pascal OSStatus MyEventHandler  (EventHandlerCallRef    nextHandler,
     EventRef            event,
     void *           userData);

EventHandlerUPP     gMyEventHandlerUPP = NULL;

/*
この配列は、MyEventHandler() が処理できるイベントを指定する
*/
static const EventTypeSpec sMyEventHandlerEvents[] =
     {
     { kEventClassWindow, kEventWindowFocusAcquired },
     { kEventClassWindow, kEventWindowFocusRelinquish },
     };
...

/*
フォントパネルをサポートするために、各ウィンドウに Carbonイベントハンドラをインストールする
*/
gMyEventHandlerUPP = NewEventHandlerUPP(MyEventHandler);

InstallWindowEventHandler(window1Ref, gMyEventHandlerUPP,
    GetEventTypeCount(sMyEventHandlerEvents),
    sMyEventHandlerEvents, 0, NULL);

InstallWindowEventHandler(window2Ref, gMyEventHandlerUPP,
    GetEventTypeCount(sMyEventHandlerEvents),
    sMyEventHandlerEvents, 0, NULL);

...

pascal OSStatus
MyEventHandler      (EventHandlerCallRef    nextHandler,
               EventRef            event,
               void *           userData)
{
    UInt32      eventClass = GetEventClass(event);
    HICommand   command;
    WindowRef   thisWindow = NULL;
    OSStatus    status = eventNotHandledErr;

    switch ( eventClass )
    {
     case kEventClassWindow:
     {
      switch (GetEventKind(event))
      {
       case kEventWindowFocusRelinquish:
       {
           /*
           フォントパネルの設定をクリアする
           */
           status = SetFontInfoForSelection(kFontSelectionATSUIType,
                    0, NULL, NULL);
       }
       break;

       case kEventWindowFocusAcquired:
       {
           /*
           新しいターゲットがこのイベントハンドラの所有者であることを
           フォントパネルに知らせる*/
           status = GetEventParameter(event, kEventParamDirectObject,
       typeWindowRef, NULL,
       sizeof(WindowRef), NULL,
       &thisWindow);

              status = SetFontInfoForSelection(
       kFontSelectionATSUIType, 0, NULL,
       GetWindowEventTarget(thisWindow));
          }
          break;
         }
     }
     break;
    }

    return (status);

}   // MyEventHandler

先頭に戻る

フォントパネルの表示と非表示

ユーザがフォントパネルをアクティブにしたり非アクティブにしたりするためのインタフェースを提供するのは、アプリケーションの役目です。通常これは、「フォーマット」メニューまたは「フォント」メニューの「フォントパネルの表示…」または「フォントの表示…」などとなります。これに対応するキーは、command + T です。

アプリケーションに、フォントパネルをアクティブにするためにボタンなどの機能を付けることもできます。フォントパネルをアクティブにする方法の実装は、アプリケーションのニーズによって決まります。

先頭に戻る

kHICommandShowHideFontPanel

Carbon Event Manager の HICommand の kHICommandShowHideFontPanel は、フォントパネルの状態を切り替え、表示したり非表示にしたりします。アプリケーションでは、フォントパネルのアクティブ/非アクティブを切り替えるインターフェイスでの選択に応じて、Carbon Event Manager コマンドイベントが発行されるようにしなければなりません。これは、たとえばアプリケーションのフォントメニューに対応している 'xmnu' リソースへ項目を追加することで可能になります。

 リスト 4 kHICommandShowHideFontPanel HICommand を実装する 'xmnu' リソースの一部

resource 'xmnu' (131, "Font menu")
{
    versionZero
    {
     {
         /* ItemExtensions 配列:要素は 5 つ */
         ...
         /* [3] */
         dataItem
         {
          kHICommandShowHideFontPanel,
          kMenuNoModifiers,
          currScript,
          0,
          0,
          noHierID,
          sysFont,
          naturalGlyph
         },
         ...
     }
    }
};

標準の Carbon アプリケーションのイベントハンドラは、イベントの検出を検出すると、ShowHideFontPanel を呼び出して、フォントパネルの状態を切り替えることによって応えます(次の ShowHideFontPanel を参照)。

このコマンドにはパラメータはありません。

先頭に戻る

ShowHideFontPanel

ShowHideFontPanel を呼び出すと、フォントパネルは、現在表示されていなければ表示され、現在表示されていれば非表示になります。

    OSStatus ShowHideFontPanel(void);

リスト 5 に示すように、アプリケーションは、kHICommandShowHideFontPanel HICommand をサポートしていない場合、この関数を直接呼び出すこともできます。

返されるエラー状態は次のとおりです。

未知の原因によってフォントパネルを表示させることができなかった場合、fontPanelShowErr が返されます。原因がわかる場合には、具体的なエラー状態が返されます(memFullErrなど)。

 リスト 5 ShowHideFontPanel を直接呼び出す

switch ( eventClass )
{
    ...
    case kEventClassCommand:
    {
     /*
     イベントから HICommand を抽出し処理する
     */
     GetEventParameter(event, kEventParamDirectObject,
                 typeHICommand, NULL, sizeof(HICommand),
                 NULL, &command);

     switch ( command.commandID )
     {
         ...

         case kHICommandShowHideFontPanel:
         {
          /*
          フォントパネルの状態を切り替える
          */
          status = FPShowHideFontPanel();
         }
         break;

         ...
     }
    }
    ...
}

先頭に戻る

フォントパネルを閉じる

ユーザが、「閉じる」ボタンをクリックしたり、またはアプリケーションが提供するヒューマンインタフェース要素(「フォントパネルを隠す」メニュー項目など)を使ってフォントパネルを閉じると、フォントパネルは、アプリケーションが最後の SetFontInfoForSelection の呼び出しで指定したイベントターゲットに Carbon イベントを送ります。これによりアプリケーションは、フォントパネルが閉じられたことで状態を変える必要のあるメニュー項目やその他のコントロールを更新できます。このイベントを検出するためには、アプリケーションには Carbon イベントハンドラをインストールしている必要があります。

このイベントにはパラメータはありません。

このイベントは、kEventClassFont クラスに属し、kEventFontPanelClosed 型です。


注意:
WaitNextEvent を使っている場合でも、フォントパネルを閉じた時にそれを検出するためには、アプリケーションに、Carbon イベントハンドラをインストールする必要があります。


先頭に戻る

IsFontPanelVisible

    Boolean IsFontPanelVisible(void);

IsFontPanelVisible は、フォントパネルが現在表示されていれば true を返し、そうでなければ false を返します。アプリケーションは、たとえばフォントパネルの表示を制御するユーザインタフェース要素の実際の状態を確認するためにこの関数を呼び出すことができます(フォントパネルメニュー項目を有効にすべきか無効にすべきかなど)。

先頭に戻る

フォントパネル選択イベント

ユーザがフォントパネルで項目を選択すると、フォントパネルは、アプリケーションが最後に SetFontInfoForSelection を呼び出した時に指定したイベントターゲットにCarbon イベントを送ります。この Carbon イベントには、ユーザが選択したフォント設定を記述するパラメータが含まれています。アプリケーションは、この Carbon イベントからパラメータを抽出し、たとえば、選択したテキストに適用します。このイベントを検出するためには、アプリケーションに Carbon イベントハンドラをインストールしておく必要があります。


注意:
WaitNextEvent を使っている場合でも、フォントパネルから設定を取得するためには、アプリケーションに Carbon イベントハンドラをインストールする必要があります。


このイベントは、kEventClassFont クラスに属し、kEventFontSelection 型です。

このイベントには、サポートされているすべての形式で現在のフォントパネル設定を反映するパラメータが含まれています。アプリケーションは、GetEventParameter 関数を使ってこれらのパラメータを取得できます。

  • kEventParamATSUFontID, typeATSUFontID:指定されていれば、選択されたフォントのフォント ID を指定します。
  • kEventParamATSUFontSize, typeATSUSize: 指定されていれば、Fixed 型の値としてのフォントサイズを指定します。
  • kEventParamFMFontFamily, typeFMFontFamily:指定されていれば、フォントのフォントファミリ参照を指定します。
  • kEventParamFMFontStyle, typeFMFontStyle:指定されていれば、Quickdraw 形式のフォントを指定します。
  • kEventParamFMFontSize, typeFMFontSize:指定されていれば、フォントのサイズを整数で指定します。

フォントパネルは、ユーザがフォントパネルの項目を選択するたびに、この Carbon イベントをアプリケーションに送ります。選択において完全なスタイルが指定されていない場合もあります。たとえば、ユーザは、書体を指定せずにフォントを選択しているかもしれません。あるいは、フォントや書体を指定しないでサイズを選択しているかもしれません。したがって、この Carbon イベントに、上記のすべてのパラメータが、含まれているとは限りません。アプリケーションは、認識できるパラメータをすべて調べ、フォントの部分指定を、現在選択されているテキストあるいは、現在のフォント設定に、必要に応じて適用できる必要があります。

先頭に戻る

要約

Font Panel API を使うように Carbon アプリケーションを変更するのは、難しいことではなく、Cocoa アプリケーションと共通の、多くの場合フォントメニューよりも簡単で使いやすいフォント選択用のインタフェースをユーザに提供することで、Mac OS X 体験を向上させることができます。

先頭に戻る

参考文献

Apple Computer, Inc. (2002) Apple Type Services for Unicode Imaging.

Apple Computer, Inc. (2002) Carbon Event Manager.

Apple Computer, Inc. (2002) Programming Topic: Font Panel.

先頭に戻る

ダウンロード

Acrobat gif

本テクニカルノートのPDF (45K)

ダウンロード

先頭に戻る